package com.sn.pw.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sn.pw.dao.entity.*;
import com.sn.pw.dao.mapper.BiddingMapper;
import com.sn.pw.dao.mapper.CompanyMapper;
import com.sn.pw.dao.mapper.EvaluationMapper;
import com.sn.pw.dao.mapper.OrderMapper;
import com.sn.pw.page.ConventPage;
import com.sn.pw.page.PageResp;
import com.sn.pw.result.Result;
import com.sn.pw.service.OrderCompanyService;
import com.sn.pw.service.OrderService;
import com.sn.pw.vo.req.BiddingReq;
import com.sn.pw.vo.req.PickingOrderPageQueryReq;
import com.sn.pw.vo.req.ShippingOrderPageReq;
import com.sn.pw.vo.req.ShippingOrderReq;
import com.sn.pw.vo.resp.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class OrderServiceImpl extends ServiceImpl<OrderMapper, ShipOrder> implements OrderService {
    private final OrderCompanyService orderCompanyService;

    private final EvaluationMapper evaluationMapper;

    private final BiddingMapper biddingMapper;

    private final CompanyMapper companyMapper;

    private static final String BIDDING = "Bidding";

    private static final String SUCCESS = "Success";

    private static final String FAILED = "Failed";

    private static final String DELIVERED = "Delivered";

    private static final String WAITING = "Waiting";

    private static final String TRANSIT = "Transit";

    private static final String ARRIVED = "Arrived";

//    @Override
//    public List<OrderResp> getBidList(BiddingReq biddingReq) {
//        return addBidder(biddingReq.getBidStatus(), biddingReq);
//    }



    @Override
    public List<OrderResp> addBidder(BiddingReq biddingReq) {
        String type=biddingReq.getBidStatus();
        LambdaQueryWrapper<ShipOrder> lambdaQueryWrapper = Wrappers.<ShipOrder>lambdaQuery().eq(ShipOrder::getBidStatus, type)
                .like(StringUtils.hasText(biddingReq.getShippingOrderNumber()), ShipOrder::getShippingOrderNumber, biddingReq.getShippingOrderNumber());
        List<ShipOrder> list = super.list(lambdaQueryWrapper);

        Map<Long, Company> companyMap = new HashMap<>();
        List<Company> companies = companyMapper.selectList(null);
        if (StringUtils.hasText(biddingReq.getCompanyName()))
            companies = companies.stream()
                    .filter(company -> company.getCompanyName().contains(biddingReq.getCompanyName()))
                    .collect(Collectors.toList());

        for (Company company : companies)
            companyMap.put(company.getCompanyId(), company);



        return list.stream()
                .map(shipOrder -> {
                    OrderResp orderResp = BeanUtil.toBean(shipOrder, OrderResp.class);
                    LambdaQueryWrapper<Bidding> wrapper = Wrappers.<Bidding>lambdaQuery().eq(Bidding::getShippingOrderNumber, shipOrder.getShippingOrderNumber());
                    List<BiddingResp> biddingResps = BeanUtil.copyToList(biddingMapper.selectList(wrapper), BiddingResp.class);
                    orderResp.setBiddingRespList(biddingResps.stream()
                            .filter(biddingResp -> companyMap.get(biddingResp.getCompanyId()) != null)
                            .peek(biddingResp -> biddingResp.setCompanyName(companyMap.get(biddingResp.getCompanyId()).getCompanyName()))
                            .collect(Collectors.toList()));
                    return orderResp;
                })
                .collect(Collectors.toList());
    }

//    @Override
//    public List<OrderResp> getBiddingList(BiddingReq biddingReq) {
//        return addBidder(BIDDING, biddingReq);
//    }
//
//    @Override
//    public List<OrderResp> getSuccessList(BiddingReq biddingReq) {
//        return addBidder(SUCCESS, biddingReq);
//    }
//
//    @Override
//    public List<OrderResp> getFailedList(BiddingReq biddingReq)
//    {
//        return addBidder(FAILED, biddingReq);
//    }


    @Override
    public List<OrderResp> getDeliveredOrderByUserId(Long id) {
        LambdaQueryWrapper<ShipOrder> lambdaQueryWrapper = Wrappers.<ShipOrder>lambdaQuery()
                .eq(ShipOrder::getShippingStatus, DELIVERED)
                .eq(ShipOrder::getConsigneeId, id);
        List<ShipOrder> list = super.list(lambdaQueryWrapper);
        return BeanUtil.copyToList(list, OrderResp.class);
    }

    @Override
    public List<OrderResp> getEvaluationOrderByUserId(Long id) {
        List<ShipOrder> list = baseMapper.getEvaluationOrderByUserId(id);
        return BeanUtil.copyToList(list, OrderResp.class);
    }

    @Override
    public List<OrderResp> getWaitingOrderByUserId(Long id) {
        LambdaQueryWrapper<ShipOrder> lambdaQueryWrapper = Wrappers.<ShipOrder>lambdaQuery()
                .eq(ShipOrder::getShippingStatus, WAITING)
                .eq(ShipOrder::getConsigneeId, id);
        List<ShipOrder> list = super.list(lambdaQueryWrapper);
        return BeanUtil.copyToList(list, OrderResp.class);
    }

    @Override
    public List<OrderResp> getTransitOrderByUserId(Long id) {
        LambdaQueryWrapper<ShipOrder> lambdaQueryWrapper = Wrappers.<ShipOrder>lambdaQuery()
                .eq(ShipOrder::getShippingStatus, TRANSIT)
                .eq(ShipOrder::getConsigneeId, id);
        List<ShipOrder> list = super.list(lambdaQueryWrapper);
        return BeanUtil.copyToList(list, OrderResp.class);
    }

    @Override
    public List<OrderResp> getArrivedOrderByUserId(Long id) {
        LambdaQueryWrapper<ShipOrder> lambdaQueryWrapper = Wrappers.<ShipOrder>lambdaQuery()
                .eq(ShipOrder::getShippingStatus, ARRIVED)
                .eq(ShipOrder::getConsigneeId, id);
        List<ShipOrder> list = super.list(lambdaQueryWrapper);
        return BeanUtil.copyToList(list, OrderResp.class);
    }

    @Override
    public List<OrderResp> getTopFiveDataByUserId(Long id) {
        LambdaQueryWrapper<ShipOrder> lambdaQueryWrapper = Wrappers.<ShipOrder>lambdaQuery()
                .eq(ShipOrder::getBidStatus, SUCCESS)
                .or()
                .eq(ShipOrder::getBidStatus, FAILED)
                .orderByDesc(ShipOrder::getCreateTime)
                .last("limit 5");
        List<ShipOrder> list = super.list(lambdaQueryWrapper);
        return BeanUtil.copyToList(list, OrderResp.class);
    }

    @Override
    public CompanyOrderResp getMainOrderInfoByShippingOrderNumber(String shippingOrderNumber) {
        LambdaQueryWrapper<ShipOrder> lambdaQueryWrapper = Wrappers.<ShipOrder>lambdaQuery()
                .eq(ShipOrder::getShippingOrderNumber, shippingOrderNumber);
        ShipOrder orderInfo = super.getOne(lambdaQueryWrapper);
        LambdaQueryWrapper<Evaluation> wrapper = Wrappers.<Evaluation>lambdaQuery()
                .eq(Evaluation::getShippingOrderNumber, shippingOrderNumber);
        Evaluation evaluation = evaluationMapper.selectOne(wrapper);
        return new CompanyOrderResp(BeanUtil.toBean(orderInfo, OrderResp.class), BeanUtil.toBean(evaluation, EvaluationResp.class));
    }


    //todo 发布订单
    @Override
    public Result<ShippingOrderResp> publicOrder(ShippingOrderReq param) {
        QueryWrapper<ShipOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("shipping_order_number", param.getShippingOrderNumber());
        //确定要发布的订单
        ShipOrder order = this.getOne(queryWrapper);
        //修改当前出货订单的状态
        order.setPublishStatus("published");
        //设置竞价中的状态
        order.setBidStatus("Bidding");
        order.setPrice(param.getPrice());
        order.setReleaseDate(new Date());
        order.setRemark(param.getRemark());
        this.updateById(order);
        //返回修改状态后的订单
        ShippingOrderResp shippingOrderResp = BeanUtil.toBean(order, ShippingOrderResp.class);
        //把companyIdList中的id插入数据库中
        List<OrderCompany> orderCompanyList = new ArrayList<>();
        for (Long companyId : param.getCompanyIdList()) {
            OrderCompany orderCompany = new OrderCompany();
            orderCompany.setOrderId(order.getId());
            orderCompany.setCompanyId(companyId);
            orderCompanyList.add(orderCompany);
        }
        orderCompanyService.saveBatch(orderCompanyList);

        return Result.success(shippingOrderResp);

    }

    @Override
    public PageResp<ShippingOrderResp> pageRetrieveOrder(ShippingOrderPageReq pageReq) {
        IPage<ShippingOrderResp> shippingOrderRespIPage = baseMapper.pageRetrieveOrder(ConventPage.getPage(pageReq), pageReq);
        return ConventPage.getPageResp(shippingOrderRespIPage, ShippingOrderResp.class);
    }

    @Override
    public PageResp<ShippingOrderResp> findPage(PickingOrderPageQueryReq pageReq) {
        LambdaQueryWrapper<ShipOrder> queryWrapper = Wrappers.<ShipOrder>lambdaQuery().eq(ShipOrder::getPublishStatus, pageReq.getPublishStatus());
        IPage<ShipOrder> page = super.page(ConventPage.getPage(pageReq), queryWrapper);
        return ConventPage.getPageResp(page, ShippingOrderResp.class);
    }


}
